package com.wll.exportfile.excel.alibaba;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.wll.exportfile.excel.entity.FillData;
import com.wll.exportfile.excel.entity.FillData2;
import com.wll.exportfile.excel.entity.TempFillData;
import com.wll.exportfile.excel.entity.style.FillStyleData;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class EasyexcelExport {

    // 模板路径
    static final String baseTemplatePath = "E:\\my_work\\study\\exportFile\\src\\main\\resources\\excel\\alibaba\\";
    // 生成word的路径
    static final String baseFileDirXLS = "E:/temp/" + System.currentTimeMillis() + ".xls";
    static final String baseFileDirXLSX = "E:/temp/" + System.currentTimeMillis() + ".xlsx";

    @Before
    public void before() {
        System.out.println("before");
    }


    @After
    public void after() {
        System.out.println("end after");
    }

    /**
     * 数据量大的复杂填充
     * <p>
     * 这里的解决方案是 确保模板list为最后一行，然后再拼接table.还有03版没救，只能刚正面加内存。
     *
     * @since 2.1.1
     */
    @Test
    public void test1() {

        // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
        // {} 代表普通变量 {.} 代表是list的变量
        // 这里模板 删除了list以后的数据，也就是统计的这一行
        String templateFileName = baseTemplatePath + "complex.xlsx";

        ExcelWriter excelWriter = EasyExcel.write(baseFileDirXLSX).withTemplate(templateFileName).build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        // 直接写入数据
        excelWriter.fill(data(), writeSheet);
        excelWriter.fill(data2(), writeSheet);

        // 写入list之前的数据
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date", "2019年10月9日13:28:28");
        excelWriter.fill(map, writeSheet);

        // list 后面还有个统计 想办法手动写入
        // 这里偷懒直接用list 也可以用对象
        List<List<String>> totalListList = new ArrayList<List<String>>();
        List<String> totalList = new ArrayList<String>();
        totalListList.add(totalList);
        totalList.add(null);
        totalList.add(null);
        totalList.add(null);
        // 第四列
        totalList.add("统计:1000");
        // 这里是write 别和fill 搞错了
        excelWriter.write(totalListList, writeSheet);
        excelWriter.finish();
        // 总体上写法比较复杂 但是也没有想到好的版本 异步的去写入excel 不支持行的删除和移动，也不支持备注这种的写入，所以也排除了可以
        // 新建一个 然后一点点复制过来的方案，最后导致list需要新增行的时候，后面的列的数据没法后移，后续会继续想想解决方案
    }


    /**
     * 复杂的填充
     *
     * @since 2.1.1
     */
    @Test
    public void test2() {
        // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
        // {} 代表普通变量 {.} 代表是list的变量
        OnceAbsoluteMergeStrategy onceAbsoluteMergeStrategy = new OnceAbsoluteMergeStrategy(2, 2, 0, 1);
        ExcelWriter excelWriter = EasyExcel.write(baseFileDirXLSX).registerWriteHandler(onceAbsoluteMergeStrategy).withTemplate(baseTemplatePath + "simple.xlsx").build();
        WriteSheet writeSheet0 = EasyExcel.writerSheet(0).build();
        WriteSheet writeSheet1 = EasyExcel.writerSheet(1).build();

        excelWriter.fill(teamp(), writeSheet0);
        excelWriter.fill(teamp(), writeSheet1);

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date", "2019年10月9日13:28:28");
        map.put("total", 1000);
        excelWriter.fill(map, writeSheet0);
        excelWriter.fill(map, writeSheet1);
        excelWriter.finish();

    }

    @Test
    public void t01Fill07() throws Exception {
        String fileStyleTemplate = baseTemplatePath + "style.xlsx";
        String fileStyle07 = baseFileDirXLSX;
        EasyExcel.write(fileStyle07, FillStyleData.class).withTemplate(fileStyleTemplate).sheet().doFill(data3());
//        XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(fileStyle07));
//        XSSFSheet sheet = workbook.getSheetAt(0);
//        t01Fill07check(sheet.getRow(1));
//        t01Fill07check(sheet.getRow(2));
    }

    private void t01Fill07check(XSSFRow row) {
        XSSFCell cell0 = row.getCell(0);
        Assert.assertEquals("张三", cell0.getStringCellValue());
        Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
        Assert.assertEquals("FF00B050", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
        Assert.assertEquals("FF7030A0", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
        Assert.assertTrue(cell0.getCellStyle().getFont().getBold());

        XSSFCell cell1 = row.getCell(1);
        Assert.assertEquals("5", cell1.getStringCellValue());
        Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
        Assert.assertEquals("FF92D050", cell1.getCellStyle().getFillForegroundColorColor().getARGBHex());
        Assert.assertEquals("FF4BACC6", cell1.getCellStyle().getFont().getXSSFColor().getARGBHex());
        Assert.assertFalse(cell1.getCellStyle().getFont().getBold());

        XSSFCell cell2 = row.getCell(2);
        Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
        Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
        Assert.assertEquals("FFFFC000", cell2.getCellStyle().getFillForegroundColorColor().getARGBHex());
        Assert.assertEquals("FFC0504D", cell2.getCellStyle().getFont().getXSSFColor().getARGBHex());
        Assert.assertTrue(cell2.getCellStyle().getFont().getBold());

        XSSFCell cell3 = row.getCell(3);
        Assert.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
        Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
        Assert.assertEquals("FFFF0000", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
        Assert.assertEquals("FFEEECE1", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
        Assert.assertTrue(cell3.getCellStyle().getFont().getBold());

        XSSFCell cell4 = row.getCell(4);
        Assert.assertEquals("{.name}忽略，张三", cell4.getStringCellValue());
        Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
        Assert.assertEquals("FFC00000", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
        Assert.assertEquals("FF000000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
        Assert.assertFalse(cell4.getCellStyle().getFont().getBold());

        XSSFCell cell5 = row.getCell(5);
        Assert.assertEquals("空", cell5.getStringCellValue());
        Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
        Assert.assertEquals("FFF79646", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
        Assert.assertEquals("FF8064A2", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
        Assert.assertFalse(cell5.getCellStyle().getFont().getBold());
    }

    private List<FillData2> data2() {
        List<FillData2> list = new ArrayList<FillData2>();
        for (int i = 0; i < 10; i++) {
            FillData2 fillData = new FillData2();
            list.add(fillData);
            fillData.setTest("ttttttt" + i);
        }
        return list;
    }

    private List<TempFillData> teamp() {
        List<TempFillData> list = new ArrayList<TempFillData>();
        for (int i = 1; i < 11; i++) {
            TempFillData fillData = new TempFillData();
            fillData.setName("张三" + i);
            fillData.setNumber(5.2);
            list.add(fillData);
        }
        return list;
    }

    private List<FillData> data() {
        List<FillData> list = new ArrayList<FillData>();
        for (int i = 0; i < 10; i++) {
            FillData fillData = new FillData();
            list.add(fillData);
            fillData.setName("张三");
            fillData.setNumber(5.2);
        }
        return list;
    }

    private List<FillStyleData> data3() throws Exception {
        List<FillStyleData> list = ListUtils.newArrayList();
        for (int i = 0; i < 1000; i++) {
            FillStyleData fillData = new FillStyleData();
            list.add(fillData);
            fillData.setName("张三");
            fillData.setNumber(5.2);
            fillData.setDate(DateUtils.parseDate("2020-01-01 01:01:01"));
            if (i == 5) {
                fillData.setName(null);
            }
        }
        return list;
    }


}
